package paper.xml;

import javax.xml.parsers.*;
import org.xml.sax.helpers.*;
import org.xml.sax .*;
import java.io.*;
import org.xml.sax.helpers.DefaultHandler;
import java.util.*;

import paper.xml.PaperSet;

class DblpParser extends DefaultHandler
{
    static final int NONE=0,ARTICLE=1,TITLE=2,AUTHOR=3,PAGES=4, YEAR=5, VOLUME=6, WHERE=7;
    int where;
    PaperSet theSet;
    Vector cites,citedBy,authors;
    char[] buffer;
    int bLen;
    DblpParser(PaperSet set)
    {
        theSet = set;
        where = NONE;
        cites = new Vector();
        citedBy = new Vector();
        authors = new Vector();
        bLen=0;
        buffer = new char[4096];
    }

    int parseDate( String date )
    {
        if( date.length() != 10 || date.charAt(4) != '-' || date.charAt(7) != '-')
            return -1;
        int year = Integer.parseInt( date.substring(0,4) );
        int month = Integer.parseInt( date.substring(5,7) );
        int day = Integer.parseInt( date.substring(8,10) );
        return (year*32*12)+(month*32+day);
    }

    public void startElement(String uri, String localName, String qName, Attributes attributes) 
    {
        if( qName.equals("article") || qName.equals("book") || qName.equals("incollection") || qName.equals("phdthesis") || qName.equals("mastersthesis")
            || qName.equals("inproceedings"))
        {
            where = ARTICLE;
            for(int i=0; i<attributes.getLength(); i++)
            {
                if(attributes.getQName(i).equals("mdate"))
                    theSet.setCurrentDate(parseDate( attributes.getValue(i) ));
            }
        }
        else if( where == NONE)
//            System.out.println("Unrecognised record " + qName);
        if( qName.equals("title") && where == ARTICLE)
            where = TITLE;
        if( qName.equals("author")  && where == ARTICLE) 
            where = AUTHOR;
        if( qName.equals("pages") && where == ARTICLE)
            where = PAGES;
        if( qName.equals("volume") && where == ARTICLE)
            where = VOLUME;
        if( qName.equals("year") && where == ARTICLE)
            where = YEAR;
        if( qName.equals("journal") && where == ARTICLE)
            where = WHERE;
        if( qName.equals("booktitle") && where == ARTICLE)
            where = WHERE;
        bLen=0;
    }

    public void characters(char[] ch, int start, int length) 
    {
        for(int i=0; i<length; i++)
            buffer[bLen+i] = ch[start+i];
        bLen += length;

        //if( where == ARTICLE )
        //    System.out.println("Art: " + new String(ch,start,length));
    }
    public void endElement(String uri, String localName, String qName) 
    {
        if( qName.equals("article") || qName.equals("book") || qName.equals("incollection") || qName.equals("phdthesis") || qName.equals("mastersthesis")
            || qName.equals("inproceedings"))
        {
            where = NONE;
            theSet.finalise(cites,citedBy,authors);
            cites.clear();
            citedBy.clear();
            authors.clear();
        }
        if( qName.equals("year") && where == YEAR)
        {
            theSet.setCurrentYear(Integer.parseInt( new String(buffer,0,bLen)));
            where = ARTICLE;
        }
        if( qName.equals("volume") && where == VOLUME)
        {
            try {
                theSet.setCurrentVolume(Integer.parseInt( new String(buffer,0,bLen)));
            }
            catch (NumberFormatException nfe)
            {
            }
            where = ARTICLE;
        }
        if( qName.equals("pages") && where == PAGES)
        {
            try {
                String pgs = new String(buffer,0,bLen);
                int div = pgs.indexOf('-');
                if( div == -1)
                    div = pgs.indexOf('/');
//                System.out.println(pgs);
                if(div == -1) {
                    int p = Integer.parseInt( pgs );
                    theSet.setCurrentStPage(p);
                    theSet.setCurrentEndPage(p);
                } else {
                    int p = Integer.parseInt( new String(buffer,0,div) );
                    theSet.setCurrentStPage(p);
                    if( bLen-div-1 > 0)
                        theSet.setCurrentEndPage(Integer.parseInt( new String(buffer,div+1,bLen-div-1) ));
                    else
                        theSet.setCurrentEndPage(p);
                }
            } catch( NumberFormatException nfe )
            {
                // Don't store roman page numbers
            }
            where = ARTICLE;
        }
        if( (qName.equals("journal") || qName.equals("booktitle")) && where == WHERE)
        {
            theSet.setCurrentWhere(new String(buffer,0,bLen));
            where = ARTICLE;
        }
        if( qName.equals("author") && where == AUTHOR)
        {
        //    System.out.println("Auth: " + new String(ch,start,length));
            authors.add( new String(buffer,0,bLen));
            where = ARTICLE;
        }
        if( qName.equals("title") && where == TITLE)
        {
            theSet.setCurrentName(new String(buffer,0,bLen));
            where = ARTICLE;
        }
    }
}
